package com.jy.rhin.application.assembler;

import cn.org.chiss.rhin._2015.base.object.Slot;
import com.jy.framework.base.entity.Result;
import com.jy.framework.base.utils.Converter;
import com.jy.rhin.sdk.dto.notification.*;
import com.jy.rhin.sdk.dto.notification.req.CancelSubscribeDto;
import org.apache.cxf.helpers.DOMUtils;
import org.oasis_open.docs.wsn.b_2.*;
import org.springframework.util.CollectionUtils;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import javax.xml.transform.dom.DOMResult;
import javax.xml.ws.wsaddressing.W3CEndpointReference;
import java.util.ArrayList;
import java.util.List;

public class DocumentSubAndPubAssembler {

    private DocumentSubAndPubAssembler() {
    }

    public static SubscriberAndSubscribeTopicDto toDto(Subscribe message) {
        SubscriberAndSubscribeTopicDto subscribeTopicDto = new SubscriberAndSubscribeTopicDto();
        subscribeTopicDto.setSubscriber(getBusinessSubscriberDto(message.getConsumerReference()));
        subscribeTopicDto.setSubscriberTopic(getBusinessSubscribeTopicDto(message.getFilter()));
        subscribeTopicDto.setOperator("rhin");
        return subscribeTopicDto;
    }

    private static BusinessSubscriberDto getBusinessSubscriberDto(W3CEndpointReference ref) {
        BusinessSubscriberDto businessSubscriberDto = new BusinessSubscriberDto();
        if (ref != null) {
            businessSubscriberDto.setSubscriberName(getWSAAddress(ref));
            businessSubscriberDto.setSubscriberCode(getWSAAddress(ref));
            businessSubscriberDto.setInteractionType("SOAP");
            businessSubscriberDto.setSubscriberUrl(getWSAAddress(ref));
        }
        return businessSubscriberDto;
    }

    private static BusinessSubscribeTopicDto getBusinessSubscribeTopicDto(FilterType filter) {
        BusinessSubscribeTopicDto businessSubscribeTopicDto = new BusinessSubscribeTopicDto();
        if (filter != null) {
            if (filter.getTopicExpression() != null) {
                businessSubscribeTopicDto.setTopicExp(filter.getTopicExpression().getValue());
            }
            if (filter.getAdhocQuery() != null) {
                if (filter.getAdhocQuery().getId() != null) {
                    businessSubscribeTopicDto.setQueryExp(filter.getAdhocQuery().getId().getValue());
                }
                if (!CollectionUtils.isEmpty(filter.getAdhocQuery().getSlot())) {
                    businessSubscribeTopicDto.setFilters(getFilters(filter.getAdhocQuery().getSlot()));
                }
            }
        }
        return businessSubscribeTopicDto;
    }

    private static String getWSAAddress(W3CEndpointReference ref) {
        Element element = DOMUtils.createDocument().createElement("elem");
        ref.writeTo(new DOMResult(element));
        NodeList nl = element.getElementsByTagNameNS("http://www.w3.org/2005/08/addressing", "Address");
        if (nl != null && nl.getLength() > 0) {
            Element e = (Element) nl.item(0);
            return DOMUtils.getContent(e).trim();
        }
        return null;
    }

    private static List<SubscribeTopicFilterDto> getFilters(List<Slot> slots) {
        List<SubscribeTopicFilterDto> list = new ArrayList<>();
        for (Slot slot : slots) {
            SubscribeTopicFilterDto item = new SubscribeTopicFilterDto();
            if (slot.getName() != null) {
                item.setFilterExp(slot.getName().getValue());
            }
            if (slot.getValueList() != null && !CollectionUtils.isEmpty(slot.getValueList().getValue())) {
                item.setValue(slot.getValueList().getValue().get(0).getValue());
            }
            list.add(item);
        }
        return list;
    }

    public static SubscribeResponse toSubscribeResponse(Result<Long> result) {
        SubscribeResponse resp = new SubscribeResponse();
        if (result.isSuccess()) {
            resp.setSuccessMessge(result.getMsg());
        } else {
            resp.setFault(result.getMsg());
        }
        return resp;
    }

    public static CancelSubscribeDto toDto(Unsubscribe message) {
        CancelSubscribeDto dto = new CancelSubscribeDto();
        dto.setId(Converter.toLong(message.getSubscriptionId()));
        dto.setOperator("rhin");
        return dto;
    }

    public static UnsubscribeResponse toUnsubscribeResponse(Result<Boolean> result) {
        UnsubscribeResponse resp = new UnsubscribeResponse();
        if (result.isSuccess()) {
            resp.setSuccessMessge(result.getMsg());
        } else {
            resp.setFault(result.getMsg());
        }
        return resp;
    }

    public static CancelSubscribeDto toDto(PauseSubscription message) {
        CancelSubscribeDto dto = new CancelSubscribeDto();
        dto.setId(Converter.toLong(message.getSubscriptionId()));
        dto.setOperator("rhin");
        return dto;
    }

    public static PauseSubscriptionResponse toPauseSubscriptionResponse(Result<Boolean> result) {
        PauseSubscriptionResponse resp = new PauseSubscriptionResponse();
        if (result.isSuccess()) {
            resp.setSuccessMessge(result.getMsg());
        } else {
            resp.setFault(result.getMsg());
        }
        return resp;
    }

    public static CancelSubscribeDto toDto(ResumeSubscription message) {
        CancelSubscribeDto dto = new CancelSubscribeDto();
        dto.setId(Converter.toLong(message.getSubscriptionId()));
        dto.setOperator("rhin");
        return dto;
    }

    public static ResumeSubscriptionResponse toResumeSubscriptionResponse(Result<Boolean> result) {
        ResumeSubscriptionResponse resp = new ResumeSubscriptionResponse();
        if (result.isSuccess()) {
            resp.setSuccessMessge(result.getMsg());
        } else {
            resp.setFault(result.getMsg());
        }
        return resp;
    }

}
